package object3;

/**
 * 匿名内部类
 *
 * new 类或接口(参数列表){
 *   类体
 * };
 */
public class AnonymousInnerClass {

    public static void main(String[] args) {

        /*
            本质是类 内部类 该类没有名字 同时还是一个对象
            匿名内部类是定义在外部类的局部位置，比如方法中，且没有类名
         */
        Outer04 outer04 = new Outer04();
        outer04.method();
    }
}

class Outer04 {

    private int n1 = 10;//属性

    public void method() {
        //1.基于接口的匿名内部类
        /*
            需求：想使用AI接口，并创建对象
            tiger的编译类型 AI
            tiger的运行类型 匿名内部类 Outer04$1
            jdk 底层在创建匿名内部类 Outer04$1,立即马上就创建了 Outer04$1实例，并且把地址返回给 tiger
            匿名内部类使用一次就不能再使用
         */
        AI tiger = new AI() {

            @Override
            public void cry() {
                System.out.println("老虎叫唤...");
            }
        };
        System.out.println("tiger的运行类型=" + tiger.getClass());
        tiger.cry();

        //2.基于类的匿名内部类
        /*
            father 编译类型 Father
            father 运行类型 Outer04$2
            同样，底层会创建匿名内部类 Outer04$2，同时返回 其对象
         */
        Father father = new Father("jack") {

            @Override
            public void test() {
                System.out.println("匿名内部类重写了test方法...");
            }
        };
        System.out.println("father对象的运行类型=" + father.getClass());//Outer04$2
        father.test();

        //3.基于抽象类的匿名内部类
        Ani ani = new Ani(){

            @Override
            void eat() {
                System.out.println("小狗吃骨头...");
            }
        };
        ani.eat();
    }
}




interface AI {//接口

    public void cry();

}

class Tiger implements AI {

    public void cry() {
        System.out.println("老虎叫唤...");
    }
}

class Dog implements AI {

    @Override
    public void cry() {
        System.out.println("小狗汪汪...");
    }
}

class Father {

    public Father(String name) {
        System.out.println("接收到 name=" + name);
    }

    public void test(){

    }

}

abstract class Ani { //抽象类

    abstract void eat();
}